<cfcomponent output="false" extends="BaseTest">
	<cffunction name="setup" access="public" returntype="void" output="false">
		<!--- Create a Mock ESAPI object and inject a getLogger method --->
		<cfset var mockESAPI = createObject('component','mockObject') />
		<cfset var userMethods = createObject('component','UserTestMethods') />
		<cfset injectMethod(mockESAPI, userMethods, "getLogger") />
		<cfset injectMethod(mockESAPI, userMethods, "randomizer") />
		<cfset injectMethod(mockESAPI, userMethods, "setRandomizer") />
		
		<!--- Create the User object that we are testing --->
		<cfset user = createObject('component', root & 'cfesapi.org.owasp.esapi.User').init(mockESAPI) />
		
		<!--- Create a mock logger, inject the info() method and put it into the user object --->
		<cfset mockLogger =  createObject('component','mockObject') />
		<cfset injectMethod(mockLogger, userMethods, "info") />
		<cfset user.setLogger(mockLogger) />
		
		<!--- Create a mock randomizer --->
		<cfset mockRandomizer =  createObject('component','mockObject') />
		<cfset injectMethod(mockRandomizer, userMethods, "getRandomString") />
				
		<!--- Set Randomizer into mockESAPI --->
		<cfset mockESAPI.setRandomizer(mockRandomizer) />		
	</cffunction>
		
	<cffunction name="UserInitShouldReturnIstelf" access="public" returntype="void" output="false">
		<cfset assertSame(user,user) />
     	<cfset assertIsTypeOf(user,'WEB-INF.cftags.component') />
	</cffunction>

	<cffunction name="UserShouldAllowAddRole" access="public" returntype="void" output="false">
			
		<!--- Add role to user --->				
		<cfset user.addRole("roleName") />
		
		<cfset assertTrue(user.isInRole("roleName")) />
		<cfset assertFalse(user.isInRole("NotRoleName"))>
	</cffunction>
	
	<cffunction name="UserShouldAllowAddRolesFromArray" access="public" returntype="void" output="false">
		<!--- Create an array for storing roles --->
		<cfset var rolesArray = ArrayNew(1) />	
		
		<!--- Add roles to array --->
		<cfset rolesArray[1] = "Role1" />
		<cfset rolesArray[2] = "Role2" />
		<cfset rolesArray[3] = "Role3" />
		<cfset rolesArray[4] = "Role4" />
		
		<!--- Add roles to user --->				
		<cfset user.addRoles(rolesArray) />
		
		<cfset assertTrue(user.isInRole("Role1")) />
		<cfset assertTrue(user.isInRole("Role2")) />
		<cfset assertTrue(user.isInRole("Role3")) />
		<cfset assertTrue(user.isInRole("Role4")) />
		<cfset assertFalse(user.isInRole("Role5"))>
		<cfset assertFalse(user.isInRole("NotRoleName"))>
	</cffunction>
	
	<cffunction name="UserShouldAllowAddRolesFromStruct" access="public" returntype="void" output="false">
		<!--- Create an array for storing roles --->
		<cfset var rolesStruct = StructNew() />	
		
		<!--- Add roles to array --->
		<cfset rolesStruct.role1 = "Role1" />
		<cfset rolesStruct.role2 = "Role2" />
		<cfset rolesStruct.role3 = "Role3" />
		<cfset rolesStruct.role4 = "Role4" />
		
		<!--- Add roles to user --->				
		<cfset user.addRoles(rolesStruct) />
		
		<cfset assertTrue(user.isInRole("Role1")) />
		<cfset assertTrue(user.isInRole("Role2")) />
		<cfset assertTrue(user.isInRole("Role3")) />
		<cfset assertTrue(user.isInRole("Role4")) />
		<cfset assertFalse(user.isInRole("Role5"))>
		<cfset assertFalse(user.isInRole("NotRoleName"))>
	</cffunction>

	<cffunction name="UserShouldAllowBeingDisabled" access="public" returntype="void" output="false">
		<!--- Enabling first, incase the default value is disabled --->
		<cfset user.enable() />
		<cfset user.disable() />
		
		<!--- isEnabled() should return false --->
		<cfset AssertFalse(user.isEnabled()) />
	</cffunction>
	
	<cffunction name="UserShouldAllowBeingEnabled" access="public" returntype="void" output="false">
		<!--- Disable first, incase the default value is enabled --->
		<cfset user.disable() />
		<cfset user.enable() />
		
		<!--- isEnabled() should return true --->
		<cfset AssertTrue(user.isEnabled()) />
	</cffunction>
	
	<cffunction name="UserShouldAllowSetAndGetUserID" access="public" returntype="void" output="false">
		<cfset user.setUserID("fakeUserID") />
		<cfset assertEquals(user.getUserID(), "fakeUserID") />
	</cffunction>

	<cffunction name="UserShouldAllowSetAndGetUsername" access="public" returntype="void" output="false">
		<cfset user.setUsername("fakeUsername") />
		<cfset assertEquals(user.getUsername(), "fakeUsername") />
	</cffunction>

	<cffunction name="UserShouldAllowResetAndRetrieveCSRFToken" access="public" returntype="void" output="false">
		<!--- Reset the token. The method returns the new token so we can compare --->
		<cfset var token = user.resetCSRFToken() />
		
		<!--- Compare the returned token with the one retrieved using the getter --->
		<cfset assertEquals(token, user.getCSRFToken()) />
	</cffunction>
	
	<cffunction name="UserShouldAllowSetAndGetExpiration" access="public" returntype="void" output="false">
		<!--- Set local vars --->
		<cfset var returnedExpiration = "">
		
		<!--- Set a new Expiration date/time --->
		<cfset user.setExpiration("2/26/2009 13:30:00")>
		
		<!--- Get the Expiration time --->
		<cfset returnedExpiration = user.getExpiration() />
		
		<!--- Ensure is Date --->
		<cfset assertTrue(isDate(returnedExpiration)) />
		
		<!--- Compare the returned value with the previously set value --->
		<cfset assertEquals(returnedExpiration, "2/26/2009 13:30:00")>
	</cffunction>
	
	<cffunction name="UserShouldReturnFailedLoginCount" access="public" returntype="void" output="false">
		<!--- Check initial count, should be zero --->
		<cfset assertEquals(0, user.getFailedLoginCount()) />
		
		<!--- Increment --->
		<cfset user.incrementFailedLoginCount() />
		
		<!--- Check again, should be 1 --->
		<cfset assertEquals(1, user.getFailedLoginCount()) />
		
		<!--- Increment --->
		<cfset user.incrementFailedLoginCount() />
		
		<!--- Final check, should be 2 --->
		<cfset assertEquals(2, user.getFailedLoginCount()) />
	</cffunction>

	<cffunction name="UserShouldReturnLastHostAddress" access="public" returntype="void" output="false">
		<!--- Set an initial Host Address, this should be fine because the current is blank --->
		<cfset user.setLastHostAddress("192.168.0.1") />
		
		<!--- Check the getter to make sure it returns the previously set value --->
		<cfset assertEquals(user.getLastHostAddress(), "192.168.0.1") />
		
		<cftry>
			<!--- Set a new Host value, this should throw an exception --->
			<cfset AssertFalse(user.setLastHostAddress("192.168.0.2")) />
			
			<!--- Catch the exception and assertTrue so that the test passes --->
			<cfcatch type="Any">
				<cfset debug(cfcatch.type)>
				<cfset assertTrue(cfcatch.type eq "cfesapi.org.owasp.esapi.errors.AuthenticationException") />
			</cfcatch>
		</cftry>
		
	</cffunction>

	<cffunction name="UserShouldReturnLastLoginTime" access="public" returntype="void" output="false">
		<cfset user.setLastLoginTime("2006-05-09 12:30:00 PM") />
		
		<cfset assertEquals(user.getLastLoginTime(), "2006-05-09 12:30:00 PM")>
		<cfset assertTrue(IsDate(user.getLastLoginTime())) />
	</cffunction>

	<cffunction name="UserShouldReturnLastPasswordChange" access="public" returntype="void" output="false">
		<cfset user.setLastPasswordChange("2006-05-09 12:30:00 PM") />
		
		<cfset assertEquals(user.getLastPasswordChange(), "2006-05-09 12:30:00 PM")>
		<cfset assertTrue(IsDate(user.getLastPasswordChange())) />
	</cffunction>

	<cffunction name="UserShouldReturnRolesStruct" access="public" returntype="void" output="false">
		<cfset assertIsStruct(user.getRoles()) />
	</cffunction>
	
	<cffunction name="UserShouldAllowSetandGetScreenName" access="public" returntype="void" output="false">
		<cfset user.setScreenName("Daffy Duck") />
		
		<cfset assertEquals(user.getScreenName(), "Daffy Duck") />
	</cffunction>
	
	<cffunction name="UserShouldReturnIsAnonymous" access="public" returntype="void" output="false">
		<cfset user.setLoggedIn(true) />
		
		<cfset assertFalse(user.isAnonymous()) />
		
		<cfset user.setLoggedIn(false) />
		
		<cfset assertTrue(user.isAnonymous()) />
	</cffunction>
	
	<cffunction name="UserShouldReturnIsExpired" access="public" returntype="void" output="false">
		<cfset user.setLoggedIn(true) />
		
		<cfset user.setExpiration("1999-4-14 12:21 AM") />
		
		<cfset assertTrue(user.IsExpired()) />
		
		<cfset user.setExpiration(DateAdd('d', 1, Now())) />
		
		<cfset assertFalse(user.IsExpired()) />
	</cffunction>
	
	<cffunction name="UserShouldReturnIsLocked" access="public" returntype="void" output="false">
		<cfset user.lock() />
		
		<cfset assertTrue(user.isLocked()) />
		
		<cfset user.unlock(false) />
		
		<cfset assertFalse(user.isLocked()) />
	</cffunction>
	
	<cffunction name="UserShouldReturnIsLoggedIn" access="public" returntype="void" output="false">
		<cfset user.setLoggedIn(true) />
		
		<cfset assertTrue(user.isLoggedIn()) />
		
		<cfset user.setLoggedIn(false) />
		
		<cfset assertFalse(user.isLoggedIn()) />
	</cffunction>
	
	<cffunction name="UserShouldReturnLastFailedLogin" access="public" returntype="void" output="false">
		<cfset user.setLastFailedLogin('2009-5-14 12:00:00 PM') />
		
		<cfset assertEquals(user.getLastFailedLogin(), '2009-5-14 12:00:00 PM') />
	</cffunction>
	
	<cffunction name="UserShouldAllowRoleRemoval" access="public" returntype="void" output="false">
		<!--- Create an array for storing roles --->
		<cfset var rolesArray = ArrayNew(1) />	
		
		<!--- Add roles to array --->
		<cfset rolesArray[1] = "Role1" />
		<cfset rolesArray[2] = "Role2" />
		<cfset rolesArray[3] = "Role3" />
		<cfset rolesArray[4] = "Role4" />
		<cfset rolesArray[5] = "Role5" />
		
		<!--- Add roles to user --->				
		<cfset user.addRoles(rolesArray) />
		
		<cfset assertTrue(user.isInRole("Role1")) />
		<cfset assertTrue(user.isInRole("Role2")) />
		
		<!--- Remove a role --->
		<cfset user.removeRole("Role3") />
		
		<cfset assertFalse(user.isInRole("Role3")) />
		
		<cfset assertTrue(user.isInRole("Role4")) />
		
		<!--- Remove another --->
		<cfset user.removeRole("ROLE5") />
		<cfset assertFalse(user.isInRole("Role5"))>
		
		<cfset assertFalse(user.isInRole("NotRoleName"))>
	</cffunction>
</cfcomponent>